package org.papervision3d.core.proto
{
	import org.papervision3d.Papervision3D;
	import org.papervision3d.core.log.PaperLogger;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;
	
	/**
	* <span lang="ja">SceneObject3D クラスは、全てのシーンのベースとなるクラスです。
	* シーンはオブジェクトが置かれた場所で、3D 環境を含みます。
	* シーンは、Papervision3D でレンダリングされた全てのオブジェクトを管理します。
	* 表示オブジェクトをアレンジする為に、DisplayObjectContainer3D クラスを継承します。
	* SceneObject3D は抽象基本クラスなので、直接呼び出す事はできません。</span>
	* 
	* <span lang="en">The SceneObject3D class is the base class for all scenes.
	* A scene is the place where objects are placed, it contains the 3D environment.
	* The scene manages all objects rendered in Papervision3D. It extends the DisplayObjectContainer3D class to arrange the display objects.
	* SceneObject3D is an abstract base class; therefore, you cannot call SceneObject3D directly.</span>
	*/
	public class SceneObject3D extends DisplayObjectContainer3D
	{		
		/**
		* <span lang="ja">シーンの中の DisplayObject3D オブジェクトのリストを格納します。</span>
		* <span lang="en">Contains a list of DisplayObject3D objects in the scene.</span>
		*/
		public var objects :Array;
	
		/**
		* <span lang="ja">シーンの中のマテリアルのリストを格納します。</span>
		* <span lang="en">It contains a list of materials in the scene.</span>
		*/
		public var materials:MaterialsList;
		
		/**
		* <span lang="ja">SceneObject3D クラスは、シーンのクラスを作成します。</span>
		* <span lang="en">The SceneObject3D class lets you create scene classes.</span>
		*
		* @param	container	The Sprite that you draw into when rendering. If not defined, each object must have it's own private container.
		*/
		public function SceneObject3D()
		{
			this.objects = new Array();
			this.materials = new MaterialsList();
	
			PaperLogger.info( Papervision3D.NAME + " " + Papervision3D.VERSION + " (" + Papervision3D.DATE + ")\n" );

			this.root = this;
		}
	
		/**
		* <span lang="ja">シーンに子 DisplayObject3D インスタンスを追加します。
		* GeometryObject3D シンボルを追加するときは、新しい DisplayObject3D が作成されます。</span>
		* 
		* <span lang="en">Adds a child DisplayObject3D instance to the scene.
		* If you add a GeometryObject3D symbol, a new DisplayObject3D instance is created.</span>
		*
		* [TODO: If you add a child object that already has a different display object container as a parent, the object is removed from the child list of the other display object container.]
		*
		* @param	child	The GeometryObject3D symbol or DisplayObject3D instance to add as a child of the scene.
		* @param	name	An optional name of the child to add or create. If no name is provided, the child name will be used.
		* @return	The DisplayObject3D instance that you have added or created.
		*/
		public override function addChild( child:DisplayObject3D, name:String=null ):DisplayObject3D
		{
			var newChild:DisplayObject3D =	super.addChild( child, name ? name : child.name );
			child.scene = this;
			child.parent = null;
			this.objects.push( newChild );
			return newChild;
		}
	
		/**
		* <span lang="ja">特定の子 DisplayObject3D インスタンスを、その子とシーンのオブジェクトリストから削除します。
		* 
		* ガーベージコレクターは、使用されないメモリスペースを Flash Player によって再割り当てするプロセスです。
		* 変数またはオブジェクトが、これからどこかで参照または格納されないとき、
		* メモリスペースのためにそれらを削除します。</span>
		* 
		* 
		* <span lang="en">Removes the specified child DisplayObject3D instance from the child and object list of the scene.
		* [TODO: The parent property of the removed child is set to null, and the object is garbage collected if no other references to the child exist.]
		* The garbage collector is the process by which Flash Player reallocates unused memory space. 
		* When a variable or object is no longer actively referenced or stored somewhere,
		* the garbage collector sweeps through and wipes out the memory space it used to occupy if no other references to it exist.</span>
		* 
		* @param	child	The DisplayObject3D instance to remove.
		* @return	The DisplayObject3D instance that you pass in the child parameter.
		*/
		public override function removeChild( child:DisplayObject3D ):DisplayObject3D
		{
			super.removeChild( child );
	
			for (var i:int = 0; i < this.objects.length; i++ )
			{
				if (this.objects[i] === child )
				{
					this.objects.splice(i, 1);
					return child;
				}
			}
			return child;
		}
				
			
	}
}
